package com.hl.card.credit.pub.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.apache.commons.lang.math.NumberUtils;
import org.springframework.stereotype.Component;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;

import com.hl.card.credit.pub.utils.StringUtils;

/**
 * 内存数据库Redis的辅助类，负责对内存数据库的所有操作
 * @version V1.0
 */
//@Component
public class RedisUtil {
	public static final Random RANDOM = new Random();

	// 数据源
		private static JedisPool jedisPool=RedisClient.getJedisPool();;



		public RedisUtil() {
		}
		private static final RedisUtil redisUtil=new RedisUtil();
		public static RedisUtil getInstance(){
			return redisUtil;
		}
		
		//获取key的过期时间没有则返回-1
		public Long ttl(final String key) {
			return new Executor <Long> (jedisPool) {
				@Override
				Long execute() {
					return jedis.ttl(key);
				}
			}.getResult();
		}
		//获取该key的类型
		public String type(final String key) {
			return new Executor <String> (jedisPool) {
				@Override
				String execute() {
					return jedis.type(key);
				}
			}.getResult();
		}
		public String ping() {
			return new Executor <String> (jedisPool) {
				@Override
				String execute() {
					return jedis.ping();
				}
			}.getResult();
		}
		/**获取模糊到的key的集合
		 * @param likeKey 需要模糊匹配的key
		 * @return
		 */
		public Set<String> selLike(final String likeKey) {
			return new Executor<Set<String>>(jedisPool) {
				@Override
				Set<String> execute() {
					return jedis.keys(likeKey);
				}
			}.getResult();
		}
		/**
		 * 删除模糊匹配的key
		 * @param likeKey 模糊匹配的key
		 * @return 删除成功的条数
		 */
		public long delKeysLike(final String likeKey) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					
					return jedis.del(likeKey + "*");
				}
			}.getResult();
		}
		
		/**
		 * 删除key里面包含的所有数据
		 * @param key 存键的对象
		 * @param key2 需要删除的对象的前缀
		 * @return
		 */
		public long delMultipleString(final String key,final String key2) {
			return new Executor<Long>(jedisPool) {
				@Override
				Long execute() {
					long count = 0;
					String[] keys=key.split(",");
					for (int i = 0; i < keys.length; i++) {
						count+=jedis.del(key2+""+keys[i]);
					}
					return count;
				}
			}.getResult();
		}
		
		/**
		 * 判断该键是否存在
		 * @param key
		 * @return 存在返回true
		 */
		public Boolean existsKey(final String key) {
			return new Executor<Boolean>(jedisPool) {

				@Override
				Boolean execute() {
					return jedis.exists(key);
				}
			}.getResult();
		}
		
		/**
		 * 存在就添加，不存在就创建
		 * @param key 键
		 * @param value 需要添加的值
		 * @return
		 */
		public String existsKeyAppend(final String key,final String value) {
			return new Executor<String>(jedisPool) {
				@Override
				String execute() {
					if(jedis.exists(key)){
						jedis.append(key, ","+value);
					}else{
						jedis.set(key, value);
					}
					return "ok";
				}
			}.getResult();
		}

		/**
		 * 删除
		 * @param key 匹配的key  单条
		 * @return 删除成功的条数
		 */
		public Long delKey(final String key) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.del(key);
				}
			}.getResult();
		}
		
		/**
		 * 删除
		 * @param keys 匹配的key的集合
		 * @return 删除成功的条数
		 */
		public Long delKeys(final String[] keys) {
			return new Executor<Long>(jedisPool) {
				@Override
				Long execute() {
					return jedis.del(keys);
				}
			}.getResult();
		}
		/** 获取某个key下面的所有key
		 * @param key
		 * @return
		 */
		public Set<String> getKey(final String key){
			return new Executor<Set<String>>(jedisPool) {

				@Override
				Set<String> execute() {
//					Jedis shard = jedis.getShard(key);
					Set<String> keys = jedis.keys(key);
					return keys;
				}
			}.getResult();
		}
		/**
		 * 为给定 key 设置生存时间，当 key 过期时(生存时间为 0 )，它会被自动删除。
		 * 在 Redis 中，带有生存时间的 key 被称为『可挥发』(volatile)的。
		 * @param key key
		 * @param expire 生命周期，单位为秒
		 * @return 1: 设置成功 0: 已经超时或key不存在
		 */
		public Long expire(final String key, final int expire) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.expire(key, expire);
				}
			}.getResult();
		}

		/**
		 * 一个跨jvm的id生成器，利用了redis原子性操作的特点 (+操作)
		 * @param key id的key
		 * @return 返回生成的Id
		 */
		public long makeId(final String key) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					long id = jedis.incr(key);
					if ((id + 75807) >= Long.MAX_VALUE) {
						// 避免溢出，重置，getSet命令之前允许incr插队，75807就是预留的插队空间
						jedis.getSet(key, "0");
					}
					return id;
				}
			}.getResult();
		}
		/** 设置了生存时间 ,存在则直接返回2 , +操作
		 * @param key
		 * @param expire
		 * @return
		 */
		public long incrToGO(final String key, final int expire) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					if (existsKey(key)) {
						//存在此key返回2
						return 2l;
					}
					long id = jedis.incr(key);
					if ((id + 75807) >= Long.MAX_VALUE) {
						// 避免溢出，重置，getSet命令之前允许incr插队，75807就是预留的插队空间
						jedis.getSet(key, "0");
					}
					//当ttl不存在的时候再给其设置过期时间
					Long ttl = ttl(key);
					if (ttl==-1) {
						expire(key, expire);
					}
					return id;
				}
			}.getResult();
		}
		/**
		 * 一个跨jvm的id生成器，利用了redis原子性操作的特点 (-操作)
		 * @param key id的key
		 * @return 返回生成的Id
		 */
		public long decr(final String key) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					long id = jedis.decr(key);
					if ((id + 75807) >= Long.MAX_VALUE) {
						jedis.getSet(key, "0");
					}
					return id;
				}
			}.getResult();
		}
		
		public long incr(final String key, final long num, final int expire) {
			return new Executor<Long>(jedisPool) {
				
				@Override
				Long execute() {
					long id = jedis.incrBy(key, num);
					if ((id + 75807) >= Long.MAX_VALUE) {
						// 避免溢出，重置，getSet命令之前允许incr插队，75807就是预留的插队空间
						jedis.getSet(key, "0");
					}
					//当ttl不存在的时候再给其设置过期时间
					if (expire!=0) {
						Long ttl = ttl(key);
						if (ttl==-1) {
							expire(key, expire);
						}
					}
					return id;
				}
			}.getResult();
		}
		public double incr(final String key, final double num, final int expire) {
			return new Executor<Double>(jedisPool) {

				@Override
				Double execute() {
					Double id = jedis.incrByFloat(key, num);
					if ((id + 75807) >= Double.MAX_VALUE) {
						// 避免溢出，重置，getSet命令之前允许incr插队，75807就是预留的插队空间
						jedis.getSet(key, "0");
					}
					//当ttl不存在的时候再给其设置过期时间
					if (expire!=0) {
						Long ttl = ttl(key);
						if (ttl==-1) {
							expire(key, expire);
						}
					}
					return id;
				}
			}.getResult();
		}
		/** 每次都更新过期时间 
		 * @param key
		 * @param num
		 * @param expire
		 * @return
		 */
		public double incrExpire(final String key, final double num, final int expire) {
			return new Executor<Double>(jedisPool) {

				@Override
				Double execute() {
					Double id = jedis.incrByFloat(key, num);
					if ((id + 75807) >= Double.MAX_VALUE) {
						// 避免溢出，重置，getSet命令之前允许incr插队，75807就是预留的插队空间
						jedis.getSet(key, "0");
					}
					if (expire!=0) {
						expire(key, expire);
					}
					return id;
				}
			}.getResult();
		}
		
		/**
		 * 
		    * @Title: incrExpireOrderCode
		    * @Description: TODO(商户订单编号自增处理)
		    * @param @param key
		    * @param @param num
		    * @param @param expire
		    * @param @return    参数
		    * @return Integer    返回类型
		    * @throws
		 */
		public Integer incrExpireOrderCode(final String key, final int num, final int expire) {
			return new Executor<Integer>(jedisPool) {

				@Override
				Integer execute() {
					Long id = jedis.incrBy(key, num);
					if ((id + 75807) >= Integer.MAX_VALUE) {
						// 避免溢出，重置，getSet命令之前允许incr插队，75807就是预留的插队空间
						jedis.getSet(key, "0");
					}
					if (expire!=0) {
						expire(key, expire);
					}
					return id.intValue();
				}
			}.getResult();
		}
		
		public double incrExpireNoLtZero(final String key, final double num, final int expire) {
			return new Executor<Double>(jedisPool) {

				@Override
				Double execute() {
					Double id = jedis.incrByFloat(key, num);
					if ((id + 75807) >= Double.MAX_VALUE) {
						// 避免溢出，重置，getSet命令之前允许incr插队，75807就是预留的插队空间
						jedis.getSet(key, "0");
					}
					if(id<0){
						jedis.getSet(key, "0");
					}
					if (expire!=0) {
						expire(key, expire);
					}
					return id;
				}
			}.getResult();
		}
		/* ======================================set====================================== */
		//查
		public  Set<String> setGet(final String key) {
			return new Executor< Set<String>>(jedisPool) {
				@Override
				 Set<String> execute() {
					return jedis.smembers(key);
				}
			}.getResult();
		}
		
		//返回set集合大小
		public Long sSize(final String key) {
			return new Executor<Long>(jedisPool) {
				@Override
				Long execute() {
					return jedis.scard(key);
				}
			}.getResult();
		}
		//增
		public Long sadd(final String key,final String... members) {
			return new Executor<Long>(jedisPool) {
				@Override
				 Long execute() {
					return jedis.sadd(key, members);
				}
			}.getResult();
		}
		
		//增,添加过期时间
		public Long sadd(final String key,final Integer ttl,final String... members) {
			return new Executor<Long>(jedisPool) {
				@Override
				 Long execute() {
					 Long sadd = jedis.sadd(key, members);
					 jedis.expire(key, ttl);
					 return sadd;
				}
			}.getResult();
		}

		// 删除set中的一个key
		public Long srem(final String key, final String members) {
			return new Executor<Long>(jedisPool) {
				@Override
				Long execute() {
					
					return jedis.srem(key, members);
				}
			}.getResult();
		}
		// 根据key删除set中的value
		public Long srem(final String key, final String... members) {
			return new Executor<Long>(jedisPool) {
				@Override
				Long execute() {
					
					return jedis.srem(key, members);
				}
			}.getResult();
		}
		
		/**随机返回一个值,并且删除
		 * @param key
		 * @return
		 */
		public String spop(final String key) {
			return new Executor<String>(jedisPool) {
				@Override
				String execute() {
					String spop = jedis.spop(key);
					return spop;
				}
			}.getResult();
		}
		
		/**随机删除count个值 并返回删除的值
		 * @param key
		 * @return
		 */
		public Set<String> spop(final String key,final long count) {
			return new Executor<Set<String>>(jedisPool) {
				@Override
				Set<String> execute() {
					Set<String> spop = jedis.spop(key,count);
					return spop;
				}
			}.getResult();
		}
		
		// 判断 此set集合中是否有此member值
		public Boolean sismember(final String key,final String member) {
			return new Executor<Boolean>(jedisPool) {
				@Override
				Boolean execute() {
					Boolean sismember = jedis.sismember(key, member);
					return sismember;
				}
			}.getResult();
		}
		/**
		 * 随机返回set里的一个值
		 * @param key
		 * @return
		 */
		public String srandmember(final String key) {
			return new Executor<String>(jedisPool) {
				@Override
				String execute() {
					String srandmember = jedis.srandmember(key);
					return srandmember;
				}
			}.getResult();
		}
	/*
	 * ======================================Strings==============================
	 * ========
	 */

		/**
		 * 返回Set集合 key 的基数(集合中元素的数量)。
		 * 当 key 不存在时，返回 0
		 * @param key
		 * @return
		 */
		public Long getSetSize(final String key) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.scard(key);
				}
			}.getResult();
		}
		
		/**
		 * 将字符串值 value 关联到 key 。
		 * 如果 key 已经持有其他值， setString 就覆写旧值，无视类型。
		 * 对于某个原本带有生存时间（TTL）的键来说， 当 setString 成功在这个键上执行时， 这个键原有的 TTL 将被清除。
		 * 时间复杂度：O(1)
		 * @param key key
		 * @param value string value
		 * @return 在设置操作成功完成时，才返回 OK 。
		 */
		public String setString(final String key, final String value) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					return jedis.set(key, value);
				}
			}.getResult();
		}

		/**
		 * 将值 value 关联到 key ，并将 key 的生存时间设为 expire (以秒为单位)。
		 * 如果 key 已经存在， 将覆写旧值。
		 * 类似于以下两个命令:
		 * SET key value
		 * EXPIRE key expire # 设置生存时间
		 * 不同之处是这个方法是一个原子性(atomic)操作，关联值和设置生存时间两个动作会在同一时间内完成，在 Redis 用作缓存时，非常实用。
		 * 时间复杂度：O(1)
		 * @param key key
		 * @param value string value
		 * @param expire 生命周期
		 * @return 设置成功时返回 OK 。当 expire 参数不合法时，返回一个错误。
		 */
		public String setString(final String key, final String value, final int expire) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					return jedis.setex(key, expire, value);
				}
			}.getResult();
		}

		/**
		 * 将 key 的值设为 value ，当且仅当 key 不存在。若给定的 key 已经存在，则 setStringIfNotExists 不做任何动作。
		 * 时间复杂度：O(1)
		 * @param key key
		 * @param value string value
		 * @return 设置成功，返回 1 。设置失败，返回 0 。
		 */
		public Long setStringIfNotExists(final String key, final String value) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.setnx(key, value);
				}
			}.getResult();
		}
		/**命令为指定的 key 设置值及其过期时间。如果 key 已经存在， SETEX 命令将会替换旧的值。
		 * @param key
		 * @param value
		 * @param expire
		 * @return
		 */
		public String setex(final String key, final String value, final int expire) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					return jedis.setex(key, expire, value);
				}
			}.getResult();
		}
		/**
		 * 返回 key 所关联的字符串值。如果 key 不存在那么返回特殊值 nil 。
		 * 假如 key 储存的值不是字符串类型，返回一个错误，因为 getString 只能用于处理字符串值。
		 * 时间复杂度: O(1)
		 * @param key key
		 * @return 当 key 不存在时，返回 nil ，否则，返回 key 的值。如果 key 不是字符串类型，那么返回一个错误。
		 */
		public String getString(final String key) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					return jedis.get(key);
				}
			}.getResult();
		}
		
		/**
		 * 批量的 {@link #setString(String, String)}
		 * @param pairs 键值对数组{数组第一个元素为key，第二个元素为value}
		 * @return 操作状态的集合
		 */
		public List<Object> batchSetString(final List<Pair<String, String>> pairs) {
			return new Executor<List<Object>>(jedisPool) {

				@Override
				List<Object> execute() {
					Pipeline pipeline = jedis.pipelined();
					for (Pair<String, String> pair : pairs) {
						pipeline.set(pair.getKey(), pair.getValue());
					}
					return pipeline.syncAndReturnAll();
				}
			}.getResult();
		}

		/**
		 * 批量的 {@link #getString(String)}
		 * @param keys key数组
		 * @return value的集合
		 */
		public List<String> batchGetString(final String[] keys) {
			return new Executor<List<String>>(jedisPool) {

				@Override
				List<String> execute() {
					Pipeline pipeline = jedis.pipelined();
					List<String> result = new ArrayList<String>(keys.length);
					List<Response<String>> responses = new ArrayList<Response<String>>(keys.length);
					for (String key : keys) {
						responses.add(pipeline.get(key));
					}
					pipeline.sync();
					for (Response<String> resp : responses) {
						result.add(resp.get());
					}
					return result;
				}
			}.getResult();
		}
		
		/* ======================================Hashes====================================== */

		/**
		 * 将哈希表 key 中的域 field 的值设为 value 。
		 * 如果 key 不存在，一个新的哈希表被创建并进行 hashSet 操作。
		 * 如果域 field 已经存在于哈希表中，旧值将被覆盖。
		 * 时间复杂度: O(1)
		 * @param key key
		 * @param field 域
		 * @param value string value
		 * @return 如果 field 是哈希表中的一个新建域，并且值设置成功，返回 1 。如果哈希表中域 field 已经存在且旧值已被新值覆盖，返回 0 。
		 */
		public Long hashSet(final String key, final String field, final String value) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.hset(key, field, value);
				}
			}.getResult();
		}

		/**
		 * 将哈希表 key 中的域 field 的值设为 value 。
		 * 如果 key 不存在，一个新的哈希表被创建并进行 hashSet 操作。
		 * 如果域 field 已经存在于哈希表中，旧值将被覆盖。
		 * @param key key
		 * @param field 域
		 * @param value string value
		 * @param expire 生命周期，单位为秒
		 * @return 如果 field 是哈希表中的一个新建域，并且值设置成功，返回 1 。如果哈希表中域 field 已经存在且旧值已被新值覆盖，返回 0 。
		 */
		public Long hashSet(final String key, final String field, final String value, final int expire) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					Pipeline pipeline = jedis.pipelined();
					Response<Long> result = pipeline.hset(key, field, value);
					
					pipeline.expire(key, expire);
					pipeline.sync();
					return result.get();
				}
			}.getResult();
		}
		/**
		 * 将哈希表 key 中的域 field 的值设为 value 。
		 * 如果 key 不存在，一个新的哈希表被创建并进行 hashSet 操作。
		 * 如果域 field 已经存在于哈希表中，旧值将被覆盖。
		 * @param key key
		 * @param objMap 
		 * @param expire 生命周期，单位为秒
		 * @return 如果 field 是哈希表中的一个新建域，并且值设置成功，返回 1 。如果哈希表中域 field 已经存在且旧值已被新值覆盖，返回 0 。
		 */
		public String hashmSet(final String key, final Map<String, String>objMap, final int expire) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					Pipeline pipeline = jedis.pipelined();
					Response<String> hmset = pipeline.hmset(key, objMap);
					pipeline.expire(key, expire);
					pipeline.sync();
					return hmset.get();
				}
			}.getResult();
		}
		/**
		 * @param key 
		 * @param objMap 要存入这个key的map集合
		 * @return
		 */
		public String hashmSet(final String key, final Map<String, String>objMap) {
			return new Executor<String>(jedisPool) {
				@Override
				String execute() {
					 return jedis.hmset(key, objMap);
				}
			}.getResult();
		}
		
		public Double hincrby(final String key, final String field, final Double value) {
			return new Executor<Double>(jedisPool) {

				@Override
				Double execute() {
					return jedis.hincrByFloat(key, field, value);
				}
			}.getResult();
		}
		
		/**对key里面的field里面的值进行+value操作 
		 * @param key
		 * @param field
		 * @param value
		 * @return
		 */
		public Long hincrby(final String key, final String field, final Integer value) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.hincrBy(key, field, value);
				}
			}.getResult();
		}
		
		/**对key里面的field里面的值进行+value操作
		 *   但是 filed的值不会小于0
		 * @param key
		 * @param field
		 * @param value
		 * @return
		 */
		public Long hincrbyNoLessZero(final String key, final String field, final Integer value) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					Long hincrBy = jedis.hincrBy(key, field, value);
					if (hincrBy<0) {
						//当 该字段的值小于0的时候,给其加回来.不让其小于0
						hincrBy=jedis.hincrBy(key, field, -hincrBy);
					}
					return hincrBy;
				}
			}.getResult();
		}
		/***-------------------------------------------WMS专用--------------------------------------
		/**
		 * 删除list中的某一项 
		 * @param key
		 * @return
		 */
		public Long delListByKey(final String key,final String list_key)
		{
			return new Executor<Long>(jedisPool) {
				Long execute() {
					return jedis.lrem(key, 0, list_key);
				}
				
			}.getResult();
		}
		/**
		 * 删除list的第一个元素
		 * @param key
		 * @return
		 */
		public String delListFist(final String key)
		{
			return new Executor<String>(jedisPool) {
				String execute() {
					return jedis.lpop(key);
				}
			}.getResult();
		}
		/**
		 * 返回哈希表 key 中给定域 field 的值。
		 * 时间复杂度:O(1)
		 * @param key key
		 * @param field 域
		 * @return 给定域的值。当给定域不存在或是给定 key 不存在时，返回 nil 。
		 */
		public String hashGet(final String key, final String field) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					return jedis.hget(key, field);
				}
			}.getResult();
		}

		/**
		 * 返回哈希表 key 中给定域 field 的值。 如果哈希表 key 存在，同时设置这个 key 的生存时间
		 * @param key key
		 * @param field 域
		 * @param expire 生命周期，单位为秒
		 * @return 给定域的值。当给定域不存在或是给定 key 不存在时，返回 nil 。
		 */
		public String hashGet(final String key, final String field, final int expire) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					Pipeline pipeline = jedis.pipelined();
					Response<String> result = pipeline.hget(key, field);
					pipeline.expire(key, expire);
					pipeline.sync();
					return result.get();
				}
			}.getResult();
		}

		/**
		 * 同时将多个 field-value (域-值)对设置到哈希表 key 中。
		 * 时间复杂度: O(N) (N为fields的数量)
		 * @param key key
		 * @param hash field-value的map
		 * @return 如果命令执行成功，返回 OK 。当 key 不是哈希表(hash)类型时，返回一个错误。
		 */
		public String hashMultipleSet(final String key, final Map<String, String> hash) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					return jedis.hmset(key, hash);
				}
			}.getResult();
		}

		/**
		 * 同时将多个 field-value (域-值)对设置到哈希表 key 中。同时设置这个 key 的生存时间
		 * @param key key
		 * @param hash field-value的map
		 * @param expire 生命周期，单位为秒
		 * @return 如果命令执行成功，返回 OK 。当 key 不是哈希表(hash)类型时，返回一个错误。
		 */
		public String hashMultipleSet(final String key, final Map<String, String> hash, final int expire) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					Pipeline pipeline = jedis.pipelined();
					Response<String> result = pipeline.hmset(key, hash);
					pipeline.expire(key, expire);
					pipeline.sync();
					return result.get();
				}
			}.getResult();
		}

		/**
		 * 返回哈希表 key 中，一个或多个给定域的值。如果给定的域不存在于哈希表，那么返回一个 nil 值。
		 * 时间复杂度: O(N) (N为fields的数量)
		 * @param key key
		 * @param fields field的数组
		 * @return 一个包含多个给定域的关联值的表，表值的排列顺序和给定域参数的请求顺序一样。
		 */
		public List<String> hashMultipleGet(final String key, final String... fields) {
			return new Executor<List<String>>(jedisPool) {

				@Override
				List<String> execute() {
					return jedis.hmget(key, fields);
				}
			}.getResult();
		}

		/**
		 * 返回哈希表 key 中，一个或多个给定域的值。如果给定的域不存在于哈希表，那么返回一个 nil 值。
		 * 同时设置这个 key 的生存时间
		 * @param key key
		 * @param fields field的数组
		 * @param expire 生命周期，单位为秒
		 * @return 一个包含多个给定域的关联值的表，表值的排列顺序和给定域参数的请求顺序一样。
		 */
		public List<String> hashMultipleGet(final String key, final int expire, final String... fields) {
			return new Executor<List<String>>(jedisPool) {

				@Override
				List<String> execute() {
					Pipeline pipeline = jedis.pipelined();
					Response<List<String>> result = pipeline.hmget(key, fields);
					pipeline.expire(key, expire);
					pipeline.sync();
					return result.get();
				}
			}.getResult();
		}
		
		/**
		 * 批量的{@link #hashMultipleSet(String, Map)}，在管道中执行
		 * @param pairs 多个hash的多个field
		 * @return 操作状态的集合
		 */
		public List<Object> batchHashMultipleSet(final List<Pair<String, Map<String, String>>> pairs) {
			return new Executor<List<Object>>(jedisPool) {

				@Override
				List<Object> execute() {
					Pipeline pipeline = jedis.pipelined();
					for (Pair<String, Map<String, String>> pair : pairs) {
						pipeline.hmset(pair.getKey(), pair.getValue());
					}
					return pipeline.syncAndReturnAll();
				}
			}.getResult();
		}

		/**
		 * 批量的{@link #hashMultipleSet(String, Map)}，在管道中执行
		 * @param data Map<String, Map<String, String>>格式的数据
		 * @return 操作状态的集合
		 */
		public List<Object> batchHashMultipleSet(final Map<String, Map<String, String>> data) {
			return new Executor<List<Object>>(jedisPool) {

				@Override
				List<Object> execute() {
					Pipeline pipeline = jedis.pipelined();
					for (Map.Entry<String, Map<String, String>> iter : data.entrySet()) {
						pipeline.hmset(iter.getKey(), iter.getValue());
					}
					return pipeline.syncAndReturnAll();
				}
			}.getResult();
		}

		/**
		 * 批量的{@link #hashMultipleGet(String, String...)}，在管道中执行
		 * @param pairs 多个hash的多个field
		 * @return 执行结果的集合
		 */
		public List<List<String>> batchHashMultipleGet(final List<Pair<String, String[]>> pairs) {
			return new Executor<List<List<String>>>(jedisPool) {

				@Override
				List<List<String>> execute() {
					Pipeline pipeline = jedis.pipelined();
					List<List<String>> result = new ArrayList<List<String>>(pairs.size());
					List<Response<List<String>>> responses = new ArrayList<Response<List<String>>>(pairs.size());
					for (Pair<String, String[]> pair : pairs) {
						responses.add(pipeline.hmget(pair.getKey(), pair.getValue()));
					}
					pipeline.sync();
					for (Response<List<String>> resp : responses) {
						result.add(resp.get());
					}
					return result;
				}
			}.getResult();

		}

		/**
		 * 返回哈希表 key 中，所有的域和值。在返回值里，紧跟每个域名(field name)之后是域的值(value)，所以返回值的长度是哈希表大小的两倍。
		 * 时间复杂度: O(N)
		 * @param key key
		 * @return 以列表形式返回哈希表的域和域的值。若 key 不存在，返回空列表。
		 */
		public Map<String, String> hashGetAll(final String key) {
			return new Executor<Map<String, String>>(jedisPool) {

				@Override
				Map<String, String> execute() {
					return jedis.hgetAll(key);
				}
			}.getResult();
		}

		/**
		 * 返回哈希表 key 中，所有的域和值。在返回值里，紧跟每个域名(field name)之后是域的值(value)，所以返回值的长度是哈希表大小的两倍。
		 * 同时设置这个 key 的生存时间
		 * @param key key
		 * @param expire 生命周期，单位为秒
		 * @return 以列表形式返回哈希表的域和域的值。若 key 不存在，返回空列表。
		 */
		public Map<String, String> hashGetAll(final String key, final int expire) {
			return new Executor<Map<String, String>>(jedisPool) {

				@Override
				Map<String, String> execute() {
					Pipeline pipeline = jedis.pipelined();
					Response<Map<String, String>> result = pipeline.hgetAll(key);
					pipeline.expire(key, expire);
					pipeline.sync();
					return result.get();
				}
			}.getResult();
		}

		/**
		 * 批量的{@link #hashGetAll(String)}
		 * @param keys key的数组
		 * @return 执行结果的集合
		 */
		public List<Map<String, String>> batchHashGetAll(final String... keys) {
			return new Executor<List<Map<String, String>>>(jedisPool) {

				@Override
				List<Map<String, String>> execute() {
					Pipeline pipeline = jedis.pipelined();
					List<Map<String, String>> result = new ArrayList<Map<String, String>>(keys.length);
					List<Response<Map<String, String>>> responses = new ArrayList<Response<Map<String, String>>>(keys.length);
					for (String key : keys) {
						responses.add(pipeline.hgetAll(key));
					}
					pipeline.sync();
					for (Response<Map<String, String>> resp : responses) {
						result.add(resp.get());
					}
					return result;
				}
			}.getResult();
		}

		/**
		 * 批量的{@link #hashMultipleGet(String, String...)}，与{@link #batchHashGetAll(String...)}不同的是，返回值为Map类型
		 * @param keys key的数组
		 * @return 多个hash的所有filed和value
		 */
		public Map<String, Map<String, String>> batchHashGetAllForMap(final String... keys) {
			return new Executor<Map<String, Map<String, String>>>(jedisPool) {

				@Override
				Map<String, Map<String, String>> execute() {
					Pipeline pipeline = jedis.pipelined();

					// 设置map容量防止rehash
					int capacity = 1;
					while ((int) (capacity * 0.75) <= keys.length) {
						capacity <<= 1;
					}
					Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>(capacity);
					List<Response<Map<String, String>>> responses = new ArrayList<Response<Map<String, String>>>(keys.length);
					for (String key : keys) {
						responses.add(pipeline.hgetAll(key));
					}
					pipeline.sync();
					for (int i = 0; i < keys.length; ++i) {
						result.put(keys[i], responses.get(i).get());
					}
					return result;
				}
			}.getResult();
		}
		//删除hash中的key
		public Long hdel(final String key, final String field) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.hdel(key, field);
				}
			}.getResult();
		}

		/* ======================================List====================================== */

		/**
		 * 将一个或多个值 value 插入到列表 key 的表尾(最右边)。
		 * @param key key
		 * @param values value的数组
		 * @return 执行 listPushTail 操作后，表的长度
		 */
		public Long listPushTail(final String key, final String... values) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					
					return jedis.rpush(key, values);
					
				}
			}.getResult();
		}
		//设置过期时间的list插入
		public Long listPushTail(final String key, final int expire, final String... values) {
			return new Executor<Long>(jedisPool) {
				@Override
				Long execute() {
					Pipeline pipeline = jedis.pipelined();
					Response<Long> rpush = pipeline.rpush(key, values);
					pipeline.expire(key, expire);
					pipeline.sync();
					return rpush.get();
				}
			}.getResult();
		}
		/**
		 * 将一个或多个值 value 插入到列表 key 的表头
		 * @param key key
		 * @param value string value
		 * @return 执行 listPushHead 命令后，列表的长度。
		 */
		public Long listPushHead(final String key, final String value) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.lpush(key, value);
				}
			}.getResult();
		}

		/**
		 * 将一个或多个值 value 插入到列表 key 的表头
		 * @param key key
		 * @param value string value
		 * @return 执行 listPushHead 命令后，列表的长度。
		 */
		public Long listPushHead(final String key, final int expire, final String value) {
			return new Executor<Long>(jedisPool) {
				
				@Override
				Long execute() {
					Pipeline pipeline = jedis.pipelined();
					Response<Long> lpush = pipeline.lpush(key, value);
					pipeline.expire(key, expire);
					pipeline.sync();
					return lpush.get();
				}
			}.getResult();
		}
		
		/**
		 * 将一个或多个值 value 插入到列表 key 的表头, 当列表大于指定长度是就对列表进行修剪(trim)
		 * @param key key
		 * @param value string value
		 * @param size 链表超过这个长度就修剪元素
		 * @return 执行 listPushHeadAndTrim 命令后，列表的长度。
		 */
		public Long listPushHeadAndTrim(final String key, final String value, final long size) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					Pipeline pipeline = jedis.pipelined();
					Response<Long> result = pipeline.lpush(key, value);
					// 修剪列表元素, 如果 size - 1 比 end 下标还要大，Redis将 size 的值设置为 end 。
					pipeline.ltrim(key, 0, size - 1);
					pipeline.sync();
					return result.get();
				}
			}.getResult();
		}

		/**
		 * 批量的{@link #listPushTail(String, String...)}，以锁的方式实现
		 * @param key key
		 * @param values value的数组
		 * @param delOld 如果key存在，是否删除它。true 删除；false: 不删除，只是在行尾追加
		 */
		public void batchListPushTail(final String key, final String[] values, final boolean delOld) {
			new Executor<Object>(jedisPool) {

				@Override
				Object execute() {
					if (delOld) {
						RedisLock lock = new RedisLock(key, jedisPool);
						lock.lock();
						try {
							Pipeline pipeline = jedis.pipelined();
							pipeline.del(key);
							for (String value : values) {
								pipeline.rpush(key, value);
							}
							pipeline.sync();
						} finally {
							lock.unlock();
						}
					} else {
						jedis.rpush(key, values);
					}
					return null;
				}
			}.getResult();
		}

		/**
		 * 同{@link #batchListPushTail(String, String[], boolean)},不同的是利用redis的事务特性来实现
		 * @param key key
		 * @param values value的数组
		 * @return null
		 */
		public Object updateListInTransaction(final String key, final List<String> values) {
			return new Executor<Object>(jedisPool) {

				@Override
				Object execute() {
					Transaction transaction = jedis.multi();
					transaction.del(key);
					for (String value : values) {
						transaction.rpush(key, value);
					}
					transaction.exec();
					return null;
				}
			}.getResult();
		}

		/**
		 * 在key对应list的尾部部添加字符串元素,如果key存在，什么也不做
		 * @param key key
		 * @param values value的数组
		 * @return 执行insertListIfNotExists后，表的长度
		 */
		public Long insertListIfNotExists(final String key, final String[] values) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					RedisLock lock = new RedisLock(key, jedisPool);
					lock.lock();
					try {
						if (!jedis.exists(key)) {
							return jedis.rpush(key, values);
						}
					} finally {
						lock.unlock();
					}
					return 0L;
				}
			}.getResult();
		}

		/**
		 * 返回list所有元素，下标从0开始，负值表示从后面计算，-1表示倒数第一个元素，key不存在返回空列表
		 * @param key key
		 * @return list所有元素
		 */
		public List<String> listGetAll(final String key) {
			return new Executor<List<String>>(jedisPool) {

				@Override
				List<String> execute() {
					return jedis.lrange(key, 0, -1);
				}
			}.getResult();
		}

		/**
		 * 返回指定区间内的元素，下标从0开始，负值表示从后面计算，-1表示倒数第一个元素，key不存在返回空列表
		 * @param key key
		 * @param beginIndex 下标开始索引（包含）
		 * @param endIndex 下标结束索引（不包含）
		 * @return 指定区间内的元素
		 */
		public List<String> listRange(final String key, final long beginIndex, final long endIndex) {
			return new Executor<List<String>>(jedisPool) {

				@Override
				List<String> execute() {
					return jedis.lrange(key, beginIndex, endIndex - 1);
				}
			}.getResult();
		}

		/**
		 * 一次获得多个链表的数据
		 * @param keys key的数组
		 * @return 执行结果
		 */
		public Map<String, List<String>> batchGetAllList(final List<String> keys) {
			return new Executor<Map<String, List<String>>>(jedisPool) {

				@Override
				Map<String, List<String>> execute() {
					Pipeline pipeline=jedis.pipelined();
					Map<String, List<String>> result = new HashMap<String, List<String>>();
					List<Response<List<String>>> responses = new ArrayList<Response<List<String>>>(keys.size());
					for (String key : keys) {
						responses.add(pipeline.lrange(key, 0, -1));
					}
					pipeline.sync();
					for (int i = 0; i < keys.size(); ++i) {
						result.put(keys.get(i), responses.get(i).get());
					}
					return result;
				}
			}.getResult();
		}

		/**
		 * 返回指定key的长度
		 * @param key key
		 * @return List长度
		 */
		public Long listSize(final String key) {
			return new Executor<Long>(jedisPool) {
				@Override
				Long execute() {
					return jedis.llen(key);
				}
			}.getResult();
		}
		
		/**
		 * 返回列表 key 中，下标为 index 的元素
		 * @param key
		 * @param index
		 * @return
		 */
		public String listIndex(final String key,final int index) {
			return new Executor<String>(jedisPool) {
				@Override
				String execute() {
					return jedis.lindex(key, index);
				}
			}.getResult();
		}
		/**
		 * 根据参数 count 的值，移除列表中与参数 value 相等的元素
		 * count 的值可以是以下几种：
    		count > 0 : 从表头开始向表尾搜索，移除与 value 相等的元素，数量为 count 。
    		count < 0 : 从表尾开始向表头搜索，移除与 value 相等的元素，数量为 count 的绝对值。
    		count = 0 : 移除表中所有与 value 相等的值
		 * @param key
		 * @param count
		 * @param value
		 * @return
		 */
		public Long listRem(final String key,final long count,final String value) {
			return new Executor<Long>(jedisPool) {
				@Override
				Long execute() {
					return jedis.lrem(key, count, value);
				}
			}.getResult();
		}
		/* ======================================Pub/Sub====================================== */

		/**
		 * 将信息 message 发送到指定的频道 channel。
		 * 时间复杂度：O(N+M)，其中 N 是频道 channel 的订阅者数量，而 M 则是使用模式订阅(subscribed patterns)的客户端的数量。
		 * @param channel 频道
		 * @param message 信息
		 * @return 接收到信息 message 的订阅者数量。
		 */
		public Long publish(final String channel, final String message) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.publish(channel, message);
				}
				
			}.getResult();
		}

		/**
		 * 订阅给定的一个频道的信息。
		 * @param jedisPubSub 监听器
		 * @param channel 频道
		 */
		public void subscribe(final JedisPubSub jedisPubSub, final String channel) {
			new Executor<Object>(jedisPool) {

				@Override
				Object execute() {
					// 注意subscribe是一个阻塞操作，因为当前线程要轮询Redis的响应然后调用subscribe
					jedis.subscribe(jedisPubSub, channel);
					return null;
				}
			}.getResult();
		}

		/**
		 * 取消订阅
		 * @param jedisPubSub 监听器
		 */
		public void unSubscribe(final JedisPubSub jedisPubSub) {
			jedisPubSub.unsubscribe();
		}

		
		
		/** 移出并获取列表的最后一个元素， 
		 * 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
		 * @param timeout 等待时间 [秒]
		 * @param key
		 * @return
		 */
		public String brpop(final int timeout,final String key) {
			return new Executor<String>(jedisPool) {

				@Override
				String execute() {
					return jedis.brpop(timeout, key).get(1);
				}
			}.getResult();
		}

		/* ======================================Sorted set================================= */

		/**
		 * 将一个 member 元素及其 score 值加入到有序集 key 当中。
		 * @param key key
		 * @param score score 值可以是整数值或双精度浮点数。
		 * @param member 有序集的成员
		 * @return 被成功添加的新成员的数量，不包括那些被更新的、已经存在的成员。
		 */
		public Long addWithSortedSet(final String key, final double score, final String member) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.zadd(key, score, member);
				}
			}.getResult();
		}

		/**
		 * 将多个 member 元素及其 score 值加入到有序集 key 当中。
		 * @param key key
		 * @param scoreMembers score、member的pair
		 * @return 被成功添加的新成员的数量，不包括那些被更新的、已经存在的成员。
		 */
		public Long addWithSortedSet(final String key, final Map<String, Double> scoreMembers) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.zadd(key, scoreMembers);
				}
			}.getResult();
		}

		/**
		 * 返回有序集 key 中， score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。
		 * 有序集成员按 score 值递减(从大到小)的次序排列。
		 * @param key key
		 * @param max score最大值
		 * @param min score最小值
		 * @return 指定区间内，带有 score 值(可选)的有序集成员的列表
		 */
		public Set<String> revrangeByScoreWithSortedSet(final String key, final double max, final double min) {
			return new Executor<Set<String>>(jedisPool) {

				@Override
				Set<String> execute() {
					return jedis.zrevrangeByScore(key, max, min);
				}
			}.getResult();
		}
		
		/**
		 * 
		 * <p>Description:移除有序集中，指定排名(rank)区间内的所有成员</p>
		 * <p>Company:yssj</p>
		 * @param key
		 * @param start
		 * @param end
		 * @return
		 * 2017年9月14日
		 * @author wdf
		 */
		public Long zremrangeByRank(final String key, final long start, final long end){
			return new Executor<Long>(jedisPool) {
				@Override
				Long execute(){
					return jedis.zremrangeByRank(key, start, end);
				}
			}.getResult();
		}
		
		/**
		 * 
		 * <p>Description:获取指定区间成员</p>
		 * <p>Company:yssj</p>
		 * @param key
		 * @param start
		 * @param end
		 * @return
		 * 2017年9月14日
		 * @author wdf
		 */
		public Set<String> zrange(final String key, final long start, final long end){
			return new Executor<Set<String>>(jedisPool) {
				@Override
				Set<String> execute(){
					return jedis.zrange(key, start, end);
				}
			}.getResult();
		}
		
		/**
		 * 
		 * <p>Description:获取set的成员数</p>
		 * <p>Company:yssj</p>
		 * @param key
		 * @return
		 * 2017年9月14日
		 * @author wdf
		 */
		public Long zcard(final String key) {
			return new Executor<Long>(jedisPool) {

				@Override
				Long execute() {
					return jedis.zcard(key);
				}
			}.getResult();
		}

		/* ======================================Other====================================== */

		/**
		 * 构造Pair键值对
		 * @param key key
		 * @param value value
		 * @return 键值对
		 */
		public <K, V> Pair<K, V> makePair(K key, V value) {
			return new Pair<K, V>(key, value);
		}

		/**
		 * 键值对
		 * @version V1.0
		 * @author fengjc
		 * @param <K> key
		 * @param <V> value
		 */
		public class Pair<K, V> {

			private K key;
			private V value;

			public Pair(K key, V value) {
				this.key = key;
				this.value = value;
			}

			public K getKey() {
				return key;
			}

			public void setKey(K key) {
				this.key = key;
			}

			public V getValue() {
				return value;
			}

			public void setValue(V value) {
				this.value = value;
			}
		}
		
		/**
		 * 删除数据及该数据的key集合
		 * @param k
		 */
//		public void updateData(String k) {
//			List<String> keys=redisUtil.listGetAll(k+"keys");
//			for (String key : keys) {
//				redisUtil.delKey(k+key);
//			}
//			redisUtil.delKey(k+"keys");
//		}	
//		
//		/**
//		 * 删除数据及该数据的key集合
//		 * @param k
//		 */
//		public void updateData(String dataKey, String dataKeys) {
//			long d = 0;
//			List<String> keys=redisUtil.listGetAll(dataKeys);
//			for (String key : keys) {
//				d+=redisUtil.delKey(dataKey+key);
//			}
//			System.out.println(d);
//			redisUtil.delKey(dataKeys);
//		}	
//		
		public Integer getId(final String key,RedisAbstract redisAbstract,boolean flag){
			Integer id=0;
			String val = redisUtil.getString(key);
			if (StringUtils.isBlank(val)) {
				id= Integer.parseInt(redisAbstract.createId()+"");
				if (null==id) {
					id=0;
					id--;
				}else {
					id++;
					id*=-1;
				}
				
			}else {
				id=Integer.parseInt(val);
			}
			if (flag) {
				redisUtil.setString(key, id+1+"");
			}else {
				redisUtil.setString(key, id-1+"");
			}
			return id;
		}
		
		/**
		 * 获取指定key下的所有数据
		 * @param dataKey
		 * @param dataKeys
		 * @return
		 */
		public List<Map<String, Object>> getRedisList(final String dataKey , final String dataKeys) {
			return new Executor<List<Map<String, Object>>>(
					jedisPool) {
				List<Map<String, Object>> execute() {
					List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
					List<String> keys = jedis.lrange(dataKeys, 0, -1);
					if(null != keys && keys.size()>0){
						for (int i = keys.size()-1; i >= 0 ; i--) {
							Map<String, Object> map = new HashMap<String, Object>();
							map.putAll(jedis.hgetAll(dataKey+keys.get(i)));
							list.add(map);
						}
					}
					return list;
				}
			}.getResult();
		}
		
		/**
		 * 获取指定key下的指定区间数据
		 * @param dataKey
		 * @param dataKeys
		 * @param start
		 * @param end
		 * 取闭区间[start,end],0代表第一个，-1代表最后一个，取所有的数据则0，-1
		 * @return
		 */
		public List<Map<String, Object>> getRedisList(final String dataKey , final String dataKeys,final long start,final long end) {
			return new Executor<List<Map<String, Object>>>(
					jedisPool) {
				List<Map<String, Object>> execute() {
					List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
					List<String> keys = jedis.lrange(dataKeys, start, end);
					if(null != keys && keys.size()>0){
						for (int i = keys.size()-1; i >= 0 ; i--) {
							Map<String, Object> map = new HashMap<String, Object>();
							map.putAll(jedis.hgetAll(dataKey+keys.get(i)));
							list.add(map);
						}
					}
					return list;
				}
			}.getResult();
		}
		
		/**防止一票多卖.以此方法来增加判断
		 * 与unIsGoLock 配套使用
		 * @param key
		 * @return
		 */
		public boolean IsGotest(final String key){
			return IsGo3("Lock:"+key,200,0);
		}
		/**防止一票多卖.以此方法来增加判断
		 * 与unIsGoLock 配套使用
		 * @param key
		 * @return
		 */
		public boolean IsGo(final String key){
			return IsGo3("Lock:"+key,3,0);
		}
		@Deprecated
		public boolean IsGo(final String key,int expire){
			try {
				//给每个线程expire秒钟的执行,超时不候
				long makeId = incrToGO(key,expire);
				if (makeId==1) {
					return true;
				}else{
					//休眠150毫秒.再次执行.
					Thread.sleep(expire/4);
					IsGo(key,expire);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return true;
		}
		
		/**使用redis分布式锁 加锁方法.
		 * @param key
		 * @param expire
		 * @return
		 */
		@Deprecated
		private boolean IsGo2(final String key,int expire){
			String keyLock=key;
			try {
				//使用redis 的incr 来判断,谁抢到1就继续,否则等待
				long makeId = incrToGO(key,expire);
				if (makeId==1) {
					return true;
				}else{
					// 若超过了expire+1 秒还未取到可执行的信息,则会抛出异常.
					String brpop = brpop(expire+1, keyLock);
					if ("ok".equals(brpop)) {
						return IsGo2(key, expire);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return true;
		}
		
		
		/**使用redis分布式锁 第三个版本 <br/>
		 * 采用 redis setnx 来抢 ,  <br/>
		 * 若没抢到则  然后使用 brpop 进行等待,若等待超时抛出异常,则重头开始. <br/>
		 * 使用方法, 要和 IsGo 搭配使用,若要直接调用此方法,需重写搭配解锁的方法.
		 * @param key
		 * @param expire
		 * @return
		 */
		private boolean IsGo3(final String key,int expire,int w){
			w++;
			String keyLock=key;
			try {
				if (w>100) {
					throw new Exception("响应超时");
				}
				//使用redis 的setnx 来判断,谁抢到1就继续,否则等待
				long makeId = setStringIfNotExists(keyLock,System.currentTimeMillis()+"");
				if (makeId==1) {
					expire(keyLock, 2);
					return true;
				}else{
					String string = getString(keyLock);
					long value =NumberUtils.toLong(string);  
					if (value==0 || System.currentTimeMillis()-value>2000) {
						delKey(keyLock);
					}
					Thread.sleep(3, RANDOM.nextInt(500));
					// 若超过了expire+1 秒还未取到可执行的信息,则会抛出异常.
					String brpop = brpop(expire+1,"wait:"+ keyLock);
					//if ("ok".equals(brpop)) {
						return IsGo3(key, expire,w);
					//}
				}
			} catch (Exception e) {
				return IsGo3(key, expire,2);
			}
		}
		/**上面加锁的解锁方法. 与IsGo 配套使用
		 * @param key
		 */
		public void unIsGoLock(String key){
			try {
				key="Lock:"+key;
				delKey(key);
				//通知下一轮
				listPushHead("wait:"+ key, "ok");
				expire("wait:"+ key, 2);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		
}

